#ifndef File_h__
#define File_h__


namespace inf {
    template<typename Type>
    class TStr;

    typedef TStr<char>  Str;

    class Vec2;
    class Vec3;
    class Vec4;
    class Mat3;
    class Angles;
    class CQuat;
}

class FileSystemLocal;

class File {
	friend class FileSystemLocal;
public:

	// modes for OpenFileByMode. used as bit mask internally
	typedef enum {
		FS_READ		= 0,
		FS_WRITE	= 1,  // write/create if no exist
		FS_APPEND	= 2
	} fsMode_t;

	// mode parm for Seek - we use enums that map to the right values from system headers
	typedef enum {
		FS_SEEK_SET = 0,
		FS_SEEK_CUR,
		FS_SEEK_END
	} fsOrigin_t;

	typedef enum {
		FS_ISFILE,
		FS_ISDIR
	} fsStat_t;

	virtual const char *	GetName( void ) const =0;
	virtual const char *	GetFullPath( void ) const =0;
	virtual long long   	TimeStamp( void ) =0;

	// failed as return 0
	virtual int 			Read( void *buffer, int len ) =0;
	virtual int 			Write( const void *buffer, int len ) =0;

	virtual bool            Eof( void );
	virtual int				Length( void ) const =0;
	virtual int				Seek( long offset, fsOrigin_t origin ) = 0;
	virtual int				Tell( void ) =0;
	virtual void			ForceFlush( void ) =0;
	virtual void			Flush( void ) =0;
	virtual void			Rewind( void );

	virtual int				ReadInt( void );
	virtual unsigned int	ReadUnsignedInt( void );
	virtual short			ReadShort( void );
	virtual unsigned short	ReadUnsignedShort( void );
	virtual char			ReadChar( void );
	virtual unsigned char   ReadUnsignedChar( void );
	virtual float			ReadFloat( void );
	virtual bool			ReadBool( void );
	virtual void			ReadFloatArray( float* src, const int num );
	virtual void			ReadString( inf::Str &string );
	virtual void			ReadVec2( inf::Vec2 &vec );
	virtual void			ReadVec3( inf::Vec3 &vec );
	virtual void			ReadCQuat( inf::CQuat& quat );
	virtual void			ReadAngles( inf::Angles& angles );
	virtual void			ReadVec4( inf::Vec4 &vec );
	virtual void			ReadMat3( inf::Mat3 &mat );

	virtual void			WriteInt( const int value );
	virtual void			WriteUnsignedInt( const unsigned int value );
	virtual void			WriteShort( const short value );
	virtual void			WriteUnsignedShort( unsigned short value );
	virtual void			WriteChar( const char value );
	virtual void			WriteUnsignedChar( const unsigned char value );
	virtual void			WriteFloat( const float value );
	virtual void			WriteDouble( const double value );
	virtual void			WriteBool( const bool value );
	virtual void			WriteString( const char *string );
	virtual void			WriteFloatArray( const float* src, const int num );
	virtual void			WriteVec2( const inf::Vec2 &vec );
	virtual void			WriteVec3( const inf::Vec3 &vec );
	virtual void			WriteCQuat( const inf::CQuat& quat );
	virtual void			WriteAngles( const inf::Angles& angles );
	virtual void			WriteVec4( const inf::Vec4 &vec );
	virtual void			WriteMat3( const inf::Mat3 &mat );
protected:
	virtual					~File( void ) {}

};

class File_Permanent : public File {
	friend class			FileSystemLocal;
public:
	virtual					~File_Permanent( void ) {}

	virtual const char *	GetName( void ) const = 0;
	virtual const char *	GetFullPath( void ) const = 0;
	virtual long long       TimeStamp( void ) = 0;

	virtual int				Read( void *buffer, int len ) = 0;
	virtual int				Write( const void *buffer, int len ) = 0;

	virtual int				Length( void ) const = 0;
	virtual int				Tell( void ) = 0;
	virtual void			ForceFlush( void ) = 0;
	virtual void			Flush( void ) = 0;
	virtual int				Seek( long offset, fsOrigin_t origin ) = 0;
	virtual void			Rewind(void) = 0;	
};

class File_Memory: public File {
	friend class FileSystemLocal;
public:
	virtual ~File_Memory() {}

	virtual const char*		GetName( void ) const = 0;
	virtual const char*		GetFullPath( void ) const = 0;
	virtual long long       TimeStamp( void ) = 0;


	virtual int				Length( void ) const = 0;
	virtual int 			Read( void* buffer, int len ) = 0;
	virtual int 			Write( const void* buffer, int len ) = 0;
	virtual int				Seek( long offset, fsOrigin_t origin ) = 0;
	virtual int				Tell( void ) = 0;
	virtual void			ForceFlush( void ) = 0;
	virtual void			Flush( void ) = 0;
	virtual void			Rewind( void ) = 0;

	// spec.
	virtual void			MakeReadOnly( void ) = 0;
	virtual void			MakeWritable( void ) = 0;

	virtual void			Clear( bool freeMemory = true ) = 0;

	virtual void			SetData( const void* src, int length ) = 0;
	virtual void*			GetData() = 0;
};


#endif // File_h__
